package cn.wolfcode.exception;

import cn.wolfcode.domain.Log;
import cn.wolfcode.service.ILogService;
import cn.wolfcode.util.RequiredPermission;
import cn.wolfcode.util.UserContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author Administrator
 * @Component  把当前类注入到spring容器中
 * @Aspect 把当前类标识为一个切面供容器读取
 */
@Component
@Aspect
public class AopConfig {

    @Autowired
    private ILogService logService;
    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     * 指定切入点
     * 对贴有自定义注解@RequiredPermission的方法，进行切面
     */
    @Pointcut("@annotation(cn.wolfcode.util.RequiredPermission)")
    private void useMethod() {

    }

    /**
     * 对切入点进行增强
     */
    @Around(value = "useMethod()")
    public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//        创建Log 对象
        Log log = new Log();
        MethodSignature m = (MethodSignature)proceedingJoinPoint.getSignature();
//        获取到这个贴了的这个注解 的信息
        RequiredPermission annotation = m.getMethod().getAnnotation(RequiredPermission.class);
//        操作人
         log.setUsername(UserContext.getCurrentUser().getName());
//        权限名字(需求的用户操作)
        log.setOperation(annotation.name());
//        权限表达式(需求的请求方法)
        log.setRequestMethod(annotation.expression());
//        请求参数
        if(httpServletRequest.getQueryString() != null){
            log.setRequestArg(httpServletRequest.getQueryString());
        }

//        ip地址
        log.setIp(httpServletRequest.getRemoteAddr());
//        执行时长
        long startTime=System.currentTimeMillis();
//        操作时间
        log.setOperationTime(new Date());
        //执行处理方法（执行控制器中的方法）  执行控制层对应的方法,顺便返回他的返回值
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Exception e) {
            e.printStackTrace();
            //        操作结果
            //        错误信息
            log.setMessage(e.getMessage());
            log.setResult(false);
        }finally{
            long endTime = System.currentTimeMillis();
            log.setExecutionTime(endTime-startTime);
            logService.save(log);
        }
        return result;
    }
}